package com.yc.qunxing.websocket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yc.qunxing.entity.DriverLocations;
import com.yc.qunxing.entity.DriverVehicles;
import com.yc.qunxing.entity.Drivers;
import com.yc.qunxing.entity.Orders;
import com.yc.qunxing.exception.OrderBusinessException;
import com.yc.qunxing.service.IDriverLocationsService;
import com.yc.qunxing.service.IDriverVehiclesService;
import com.yc.qunxing.service.IDriversService;
import com.yc.qunxing.service.IOrdersService;
import com.yc.qunxing.utils.HttpClientUtil;
import com.zaxxer.hikari.util.FastList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * WebSocket服务
 */
@Component
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {

    //存放会话对象
    private static Map<String, Session> sessionMap = new HashMap();
    @Autowired
    private  IDriversService iDriversService;
    @Autowired
    private IOrdersService iOrdersService;
    @Autowired
    private IDriverVehiclesService iDriverVehiclesService;
    @Autowired
    private IDriverLocationsService iDriverLocationsService;
    @Value("${spring.baidu.ak}")
    private String ak;

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid) {
        System.out.println("客户端：" + sid + "建立连接");
        session.getUserProperties().put("id", sid); // 将司机的ID存储在Session的用户属性中
        sessionMap.put(sid, session);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, @PathParam("sid") String sid) {
        System.out.println("收到来自客户端：" + sid + "的信息:" + message);
    }

    /**
     * 连接关闭调用的方法
     *
     * @param sid
     */
    @OnClose
    public void onClose(@PathParam("sid") String sid) {
        System.out.println("连接断开:" + sid);
        sessionMap.remove(sid);
    }

    /**
     * 群发
     *
     * @param message
     */
    public void sendToAllClient(String message) {
        Collection<Session> sessions = sessionMap.values();
        System.out.println(sessions+"dafhafjaakd");
        for (Session session : sessions) {
            try {
                //服务器向客户端发送消息
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public void sendToUsers(String message){
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", "2");
        List<Orders> orders = iOrdersService.list(queryWrapper);
        for(Orders order:orders){
            for(Session session:sessionMap.values()){
                if(session!=null && order.getOrderId().toString().equals(session.getUserProperties().get("id"))){
                    try {
                        session.getBasicRemote().sendText(message);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    /*public void sendToActiveDrivers(String type,String color,String departureLocation,String message) {
        QueryWrapper<Drivers> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", "1");
        List<Drivers> activeDrivers = iDriversService.list(queryWrapper);
        QueryWrapper<DriverVehicles> queryWrapper1=new QueryWrapper<>();
        queryWrapper1.eq("vehicle_type",type).eq("color",color);
        List<DriverVehicles> list = iDriverVehiclesService.list(queryWrapper1);
        List<String> allLocations = iDriverLocationsService.getAllLocations();
        System.out.println(activeDrivers+"000000000000000");
        System.out.println(list +"88888888888888888");
        for (Drivers driver : activeDrivers) {
            for(DriverVehicles driverVehicles:list) {
                for (Session session : sessionMap.values()) {
                    for(String area : allLocations) {
                        System.out.println(session + "9865");
                        if (session != null && driver.getId().toString().equals(session.getUserProperties().get("id")) && driverVehicles.getDriverId().toString().equals(session.getUserProperties().get("id"))&&(checkOutOfRange(departureLocation,area)==true)) {
                            try {
                                session.getBasicRemote().sendText(message);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    }*/
/*    public void sendToActiveDrivers(String type, String color, String departureLocation, String message) {
        QueryWrapper<Drivers> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", "1");
        List<Drivers> activeDrivers = iDriversService.list(queryWrapper);

        QueryWrapper<DriverVehicles> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("vehicle_type", type).eq("color", color);
        List<DriverVehicles> vehicles = iDriverVehiclesService.list(queryWrapper1);

        Map<String, DriverVehicles> driverVehicleMap = vehicles.stream()
                .collect(Collectors.toMap(v -> v.getDriverId().toString(), v -> v));

        List<String> allLocations = iDriverLocationsService.getAllLocations();

        for (Drivers driver : activeDrivers) {
            String driverId = driver.getId().toString();
            DriverVehicles vehicle = driverVehicleMap.get(driverId);

            if (vehicle != null) {
                for (Session session : sessionMap.values()) {
                    if (session != null && driverId.equals(session.getUserProperties().get("id"))) {
                        for (String area : allLocations) {
                            if (checkOutOfRange(departureLocation, area)) {
                                try {
                                    session.getBasicRemote().sendText(message);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                }
            }
        }
    }*/
    public void sendToActiveDrivers(String type, String color, String departureLocation, String message) {
        // 获取所有活跃的司机
        QueryWrapper<Drivers> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", "1");
        List<Drivers> activeDrivers = iDriversService.list(queryWrapper);

        // 获取指定类型和颜色的车辆
        QueryWrapper<DriverVehicles> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("vehicle_type", type).eq("color", color);
        List<DriverVehicles> vehicles = iDriverVehiclesService.list(queryWrapper1);

        // 创建一个Map来存储每个司机的车辆信息
        Map<String, DriverVehicles> driverVehicleMap = vehicles.stream()
                .collect(Collectors.toMap(v -> v.getDriverId().toString(), v -> v));

        // 创建一个Map来存储每个司机的位置信息
        Map<String, String> driverLocationsMap = new HashMap<>();
        for (Drivers driver : activeDrivers) {
            String location = iDriverLocationsService.getLocationByDriverId(driver.getId());
            driverLocationsMap.put(driver.getId().toString(), location);
        }

        // 遍历活跃司机，发送消息
        for (Drivers driver : activeDrivers) {
            String driverId = driver.getId().toString();
            DriverVehicles vehicle = driverVehicleMap.get(driverId);

            if (vehicle != null) {
                for (Session session : sessionMap.values()) {
                    if (session != null && driverId.equals(session.getUserProperties().get("id"))) {
                        String driverLocation = driverLocationsMap.get(driverId);
                        if (driverLocation != null && checkOutOfRange(departureLocation, driverLocation)) {
                            try {
                                session.getBasicRemote().sendText(message);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    }
    /**
     * 检查客户的收货地址是否超出配送范围
     * @param address
     */
    private boolean checkOutOfRange(String address,String address1) {
        Map map = new HashMap();
        map.put("address",address1);
        map.put("output","json");
        map.put("ak",ak);

        //获取店铺的经纬度坐标
        String shopCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", map);

        JSONObject jsonObject = JSON.parseObject(shopCoordinate);
        System.out.println(jsonObject+"++++++++++++++");
        if(!jsonObject.getString("status").equals("0")){
            return false;
/*            throw new OrderBusinessException("司机地址解析失败");*/
        }

        //数据解析
        JSONObject location = jsonObject.getJSONObject("result").getJSONObject("location");
        String lat = location.getString("lat");
        String lng = location.getString("lng");
        //店铺经纬度坐标
        String shopLngLat = lat + "," + lng;

        map.put("address",address);
        //获取用户收货地址的经纬度坐标
        String userCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", map);

        jsonObject = JSON.parseObject(userCoordinate);
        if(!jsonObject.getString("status").equals("0")){
            return false;
/*            throw new OrderBusinessException("乘客地址解析失败");*/
        }

        //数据解析
        location = jsonObject.getJSONObject("result").getJSONObject("location");
        lat = location.getString("lat");
        lng = location.getString("lng");
        //用户收货地址经纬度坐标
        String userLngLat = lat + "," + lng;

        map.put("origin",shopLngLat);
        map.put("destination",userLngLat);
        map.put("steps_info","0");

        //路线规划
        String json = HttpClientUtil.doGet("https://api.map.baidu.com/directionlite/v1/driving", map);

        jsonObject = JSON.parseObject(json);
        if(!jsonObject.getString("status").equals("0")){
            return false;
/*            throw new OrderBusinessException("路线规划失败");*/
        }

        //数据解析
        JSONObject result = jsonObject.getJSONObject("result");
        JSONArray jsonArray = (JSONArray) result.get("routes");
        Integer distance = (Integer) ((JSONObject) jsonArray.get(0)).get("distance");
        System.out.println("distance = " + distance);
        if(distance > 5000){
            //配送距离超过5000米
            return false;
/*            throw new OrderBusinessException("超出发车范围");*/
        }
        return true;
    }
}